{
  "settings": {
    "hasHeaders": true,
    "constrainDragToContainer": true,
    "reorderEnabled": true,
    "selectionEnabled": false,
    "popoutWholeStack": false,
    "blockedPopoutsThrowError": true,
    "closePopoutsOnUnload": true,
    "showPopoutIcon": false,
    "showMaximiseIcon": false,
    "showCloseIcon": false,
    "responsiveMode": "onload",
    "tabOverlapAllowance": 0,
    "reorderOnTabMenuClick": true,
    "tabControlOffset": 10
  },
  "dimensions": {
    "borderWidth": 5,
    "borderGrabWidth": 15,
    "minItemHeight": 10,
    "minItemWidth": 10,
    "headerHeight": 20,
    "dragProxyWidth": 300,
    "dragProxyHeight": 200
  },
  "labels": {
    "close": "close",
    "maximise": "maximise",
    "minimise": "minimise",
    "popout": "open in new window",
    "popin": "pop in",
    "tabDropdown": "additional tabs"
  },
  "content": [
    {
      "type": "row",
      "isClosable": true,
      "reorderEnabled": true,
      "title": "",
      "content": [
        {
          "type": "stack",
          "width": 50,
          "isClosable": true,
          "reorderEnabled": true,
          "title": "",
          "activeItemIndex": 0,
          "content": [
            {
              "type": "component",
              "componentName": "codeEditor",
              "title": "ellipsebezier.json",
              "componentState": {
                "code": [
                  "// Welcome to Cascade Studio!   Here are some useful functions:",
                  "//  Translate(), Rotate(), Scale(), Union(), Difference(), Intersection()",
                  "//  Box(), Sphere(), Cylinder(), Cone(), Text3D(), Polygon()",
                  "//  Offset(), Extrude(), RotatedExtrude(), Revolve(), Pipe(), Loft(), ",
                  "//  FilletEdges(), ChamferEdges(),",
                  "//  Slider(), Button(), Checkbox()",
                  "",
                  "function Ellipse(radius1, radius2, wire) {",
                  "  let curEllipse = CacheOp(arguments, () => {",
                  "    let ellipse = new oc.GC_MakeEllipse(new oc.gp_Ax2(new oc.gp_Pnt(0, 0, 0),",
                  "      new oc.gp_Dir(0, 0, 1)), radius1, radius2).Value();",
                  "    let edge = new oc.BRepBuilderAPI_MakeEdge(ellipse).Edge();",
                  "    let ellipseWire = new oc.BRepBuilderAPI_MakeWire(edge).Wire();",
                  "    if (wire) { return ellipseWire; }",
                  "    return new oc.BRepBuilderAPI_MakeFace(ellipseWire).Face();",
                  "  });",
                  "  sceneShapes.push(curEllipse);",
                  "  return curEllipse;",
                  "}",
                  "",
                  "function NuScale(scale, shapes, keepOriginal) {",
                  "  let scaled = CacheOp(arguments, () => {",
                  "    let transformation = new oc.gp_Trsf();",
                  "    transformation.SetScaleFactor(scale);",
                  "    let scaling = new oc.TopLoc_Location(transformation);",
                  "    if (!isArrayLike(shapes)) {",
                  "      return new oc.TopoDS_Shape(shapes.Moved(scaling));",
                  "    } else if (shapes.length >= 1) {      // Do the normal rotation",
                  "      let newScale = [];",
                  "      for (let shapeIndex = 0; shapeIndex < shapes.length; shapeIndex++) {",
                  "        newScale.push(new oc.TopoDS_Shape(shapes[shapeIndex].Moved(scaling)));",
                  "      }",
                  "      return newScale;",
                  "    }",
                  "  });",
                  "",
                  "  if (!keepOriginal) { sceneShapes = Remove(sceneShapes, shapes); }",
                  "  sceneShapes.push(scaled);",
                  "",
                  "  return scaled;",
                  "}",
                  "",
                  "",
                  "// non-circular fillet",
                  "",
                  "// let nuFillet = new Sketch ([0,0])",
                  "// .LineTo([50,0])",
                  "// .LineTo([50,40])",
                  "// .BezierTo([[50,100],[0,100]])",
                  "// .BezierTo([[-50,100],[-50,40]])",
                  "// .LineTo([-50,0])",
                  "// .LineTo([0,0])",
                  "// .End().Face()",
                  "// Extrude(nuFillet,[0,0,10])",
                  "",
                  "let bmagic =  0.55228475",
                  "let xmax = 60*1.25 ",
                  "let ymax = 30",
                  "let b0 = [ 0 ,  -ymax, 0 ]",
                  "let b10 = [ xmax * bmagic , -ymax, 0]",
                  "let b20 = [ xmax          , -ymax * bmagic, 0 ]",
                  "let b25 = [ xmax , 0, 0]",
                  "let b30 = [ xmax            , ymax * bmagic, 0]",
                  "let b40 = [ xmax * bmagic ,   ymax, 0]",
                  "let b50 = [ 0 ,  ymax, 0]",
                  "",
                  "let b60 = [ -xmax * bmagic , ymax, 0]",
                  "let b70 = [ -xmax          , ymax * bmagic, 0 ]",
                  "let b80 = [ -xmax           , -ymax * bmagic, 0]",
                  "let b90 =  [-xmax * bmagic , - ymax, 0]",
                  "let b100= b0",
                  "",
                  "let marker = Cylinder(2,60)",
                  "",
                  "Translate(b10,marker,true)",
                  "Translate(b10,marker,true)",
                  "Translate(b20,marker,true)",
                  "Translate(b30,marker,true)",
                  "Translate(b40,marker,true)",
                  "Translate(b50,marker,true)",
                  "Translate(b60,marker,true)",
                  "Translate(b70,marker,true)",
                  "Translate(b80,marker,true)",
                  "Translate(b90,marker,true)",
                  "Translate(b0,marker,false)",
                  "",
                  "Translate([0,100,0], Translate(b10,marker,true))",
                  "Translate([0,100,0], Translate(b20,marker,true))",
                  "Translate([0,100,0], Translate(b30,marker,true))",
                  "Translate([0,100,0], Translate(b40,marker,true))",
                  "Translate([0,100,0], Translate(b50,marker,true))",
                  "Translate([0,100,0], Translate(b60,marker,true))",
                  "Translate([0,100,0], Translate(b70,marker,true))",
                  "Translate([0,100,0], Translate(b80,marker,true))",
                  "Translate([0,100,0], Translate(b90,marker,true))",
                  "Translate([0,100,0], Translate(b0,marker,false))",
                  "",
                  "Translate([0,200,0], Translate(b0,marker,true))",
                  "Translate([0,200,0], Translate(b10,marker,true))",
                  "Translate([0,200,0], Translate(b20,marker,true))",
                  "Translate([0,200,0], Translate(b25,marker,true))",
                  "Translate([0,200,0], Translate([0,0,0],marker,true))",
                  "",
                  "",
                  "let bezierEllipse = new Sketch (b0)",
                  ".BezierTo([b10,b20,b30,b40,b50])",
                  ".BezierTo([b60,b70,b80,b90,b0])",
                  ".End().Face()",
                  "FilletEdges(Translate([0,100,30],Extrude(bezierEllipse,[0,0,15])),3,[2,3,4,5])",
                  "",
                  "let halfEllipse = new Sketch (b0)",
                  ".BezierTo([b10,b20,b30,b40,b50])",
                  ".End(true).Face()",
                  "//Translate([0,0,45],Extrude(halfEllipse,[0,0,5]))",
                  "FilletEdges(Translate([0,100,45],Extrude(halfEllipse,[0,0,5])),1,[2,3])",
                  "",
                  "",
                  "let quartEllipse = new Sketch (b0)",
                  ".BezierTo([b10,b20,b25])",
                  ".LineTo([0,0])",
                  ".End(true).Face(true)",
                  "Rotate([0,0,1],180,quartEllipse,false)",
                  "FilletEdges(Translate([0,200,30],Extrude(quartEllipse,[0,0,5])),1,[2,3])",
                  "",
                  "",
                  "",
                  "let bSplineEllipse = new Sketch (b0)",
                  ".BSplineTo([b10,b20,b30,b40,b50])",
                  ".BSplineTo([b60,b70,b80,b90,b0])",
                  ".End().Face()",
                  "FilletEdges(Translate([0,0,0],Extrude(bSplineEllipse,[0,0,15])),3,[2,3,4,5])",
                  "",
                  "// As Arnaud Magnier told you, you can define a 3D transformation by itself (with a 4-by-4 matrix).",
                  "",
                  "// And for non uniform scaling, you just have to use this matrix:",
                  "",
                  "// M= fx 0 0 0",
                  "",
                  "// 0 fy 0 0",
                  "",
                  "// 0 0 fz 0",
                  "",
                  "// 0 0 0 0",
                  "",
                  "// where fx, fy, fz define scaling factor for every axis.",
                  "",
                  "// Regards, Thomas",
                  "",
                  "",
                  "FilletEdges(Translate([0,200,15],Extrude(Ellipse(xmax,ymax,false),[0,0,15])),3,[1,2])"
                ]
              },
              "width": 50,
              "isClosable": false,
              "reorderEnabled": true
            }
          ]
        },
        {
          "type": "column",
          "isClosable": true,
          "reorderEnabled": true,
          "title": "",
          "width": 50,
          "content": [
            {
              "type": "stack",
              "height": 80,
              "isClosable": true,
              "reorderEnabled": true,
              "title": "",
              "activeItemIndex": 0,
              "content": [
                {
                  "type": "component",
                  "componentName": "cascadeView",
                  "title": "CAD View",
                  "componentState": {
                    "componentName": "cascadeView",
                    "MeshRes": 0.1,
                    "MeshResRange": [
                      0.01,
                      2
                    ],
                    "Cache?": false,
                    "Radius": 30,
                    "RadiusRange": [
                      20,
                      40
                    ]
                  },
                  "isClosable": false,
                  "reorderEnabled": true
                }
              ]
            },
            {
              "type": "stack",
              "height": 20,
              "isClosable": true,
              "reorderEnabled": true,
              "title": "",
              "activeItemIndex": 0,
              "content": [
                {
                  "type": "component",
                  "componentName": "console",
                  "title": "Console",
                  "componentState": {},
                  "height": 20,
                  "isClosable": false,
                  "reorderEnabled": true
                }
              ]
            }
          ]
        }
      ]
    }
  ],
  "isClosable": true,
  "reorderEnabled": true,
  "title": "",
  "openPopouts": [],
  "maximisedItemId": null
}